package vip.xls8z.learning.nio.buffer;


import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;

import java.nio.IntBuffer;


@Slf4j
@DisplayName("NIO Buffer 学习")
public class BufferTests {
    private IntBuffer buffer = IntBuffer.allocate(20);


    @DisplayName("打印 '写模式下 Buffer 中属性'")
    @Test
    public void printWriteModeProperty() {
        log.info("Buffer 容量 capacity：{}， 写模式下的最大的限制 limit：{}, 写模式下的当前写入位置 position：{}", buffer.capacity(), buffer.limit(), buffer.position());
    }

    @DisplayName("打印 '读模式下 Buffer 中属性'")
    @Test
    public void printReadModeProperty() {
        log.info("Buffer 容量 capacity：{}， 读模式下的最大的限制 limit：{}, 读模式下的当前读的位置 position：{}", buffer.capacity(), buffer.limit(), buffer.position());
    }

    @DisplayName("调用allocate分配内存之后，默认是写模式。通过put方法写入数据，写入的数据类型与Buffer必须一致")
    @Order(1)
    @Test
    public void putData() {
        for (int i = 0; i < 5; i++) {
            buffer.put(i);
        }
        log.info("写入数据之后");
        printWriteModeProperty();
    }

    @DisplayName("写切换读，调用flip方法")
    @Order(2)
    @Test
    public void transferReadMode() {
        log.info("开始写入数据");
        putData();
        log.info("写转化读模式");
        buffer.flip();
        printReadModeProperty();
    }

    @DisplayName("读模式下获取数据，调用get方法")
    @Order(3)
    @Test
    public void getData() {
        transferReadMode();
        log.info("开始读数据");
        int i = buffer.get();
        log.info("读出数据：{}", i);
        printReadModeProperty();

        log.info("继续读取两个数据");
        for (int i1 = 0; i1 < 2; i1++) {
            log.info("遍历 - 读出数据：{}", buffer.get());
        }
        log.info("两个数据读取完毕");
        printReadModeProperty();
    }

    @DisplayName("读取完数据之后想再读取一遍，调用rewind方法")
    @Order(4)
    @Test
    public void rewindTest() {
        getData();

        buffer.rewind();
        log.info("调用rewind方法之后");
        printReadModeProperty();

        for (int i = 0; i < buffer.limit(); i++) {
            log.info("遍历 - 读出数据：{}", buffer.get());
        }
        printReadModeProperty();
    }

    @DisplayName("make and reset 使用。make 标记当前position，使用reset恢复到make标记的position")
    @Test
    public void makeAndreset() {

    }

    @DisplayName("从读模式切换写模式，调用clear/compact 方法")
    @Test
    public void clearTest() {
        rewindTest();
        buffer.clear();

        buffer.put(1);
        printWriteModeProperty();

        transferReadMode();
        buffer.compact();
        printWriteModeProperty();
    }
}
